﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using UT3Bots.Communications;


namespace UT3Bots.UTItems
{
	public class UTBotSelfState : UTBotState
	{
		//Self state variables
		private int _currentAmmo;

		private Dictionary<WeaponType, UTIdentifier> _inventory;


		#region Properties
		/// <summary>
		/// Ammo count for your currently selected weapon
		/// </summary>
		public int CurrentAmmo
		{
			get
			{
				return this._currentAmmo;
			}
		}
		#endregion


		internal UTBotSelfState(Message Msg)
			: base()
		{
			if (Msg.Info == InfoMessage.PLAYER_INFO && Msg.Arguments.Length == 12)
			{
				this._id = new UTIdentifier(Msg.Arguments[0]);
				this._location = UTVector.Parse(Msg.Arguments[1]);
				this._rotation = UTVector.Parse(Msg.Arguments[2]);
				this._velocity = UTVector.Parse(Msg.Arguments[3]);
				this._name = Msg.Arguments[4];
				this._health = int.Parse(Msg.Arguments[5]);
				this._armor = int.Parse(Msg.Arguments[6]);
				this._weapon = Msg.Arguments[7].GetAsWeaponType();
				this._firingType = (FireType)(int.Parse(Msg.Arguments[8]));
				this._mesh = (BotMesh)(int.Parse(Msg.Arguments[9]));
				this._colour = (BotColor)(int.Parse(Msg.Arguments[10]));
				this._currentAmmo = int.Parse(Msg.Arguments[11]);
			}

			this._inventory = new Dictionary<WeaponType, UTIdentifier>();
		}


		internal override void UpdateState(Message selfMessage)
		{
			if (selfMessage != null && selfMessage.Info == InfoMessage.SELF_INFO && selfMessage.Arguments.Length == 12)
			{
				this._currentAmmo = int.Parse(selfMessage.Arguments[11]);
			}
			base.UpdateState(selfMessage);
		}



		internal UTItem AddInventoryItem(Message msg)
		{
			UTItem newItem = new UTItem(msg);
			if (newItem.IsItem(ItemType.Weapon))
			{
				if (this._inventory.ContainsKey((WeaponType)newItem.ActualClass))
				{
					this._inventory[(WeaponType)newItem.ActualClass] = newItem.Id;
				}
				else
				{
                    this._inventory.Add((WeaponType)newItem.ActualClass, newItem.Id);
				}
			}

			return newItem;
		}


		public UTIdentifier GetInvetoryItemID(WeaponType type)
		{
			return this._inventory[type];
		}



		/// <summary>
		/// Checks to see if your bot has a weapon in it's inventory
		/// </summary>
		/// <param name="type">The weaponType to check for</param>
		/// <returns>True if your bot has this weapon</returns>
		public bool HasWeapon(WeaponType type)
		{
			return this._inventory.ContainsKey(type);
		}


		/// <summary>
		/// Checks to see if your bot is stood close to the specified location. 
		/// Useful to see if your bot has reached a Location it was running to.
		/// </summary>
		/// <param name="location">The location to check</param>
		/// <returns>True if your bot is currently stood at this location</returns>
		public bool IsCloseTo(UTVector location)
		{
			float dist = this._location.DistanceFrom(location);
			if (dist <= 200)
			{
				return true;
			}
			return false;
		}


		/// <summary>
		/// Checks to see if your bot is stood close to the specified object. 
		/// Useful to see if your bot has reached a location it was running to.
		/// </summary>
		/// <param name="toObject">The object to check</param>
		/// <returns>True if your bot is currently stood at this location</returns>
		public bool IsCloseTo(UTObject toObject)
		{
			float dist = this._location.DistanceFrom(toObject.Location);
			if (dist <= 200)
			{
				return true;
			}
			return false;
		}
	}
}
